<?php
namespace app\common\service\impl;

use app\common\client\IotCloudClient;
use app\common\controller\Gps;
use app\common\enums\ResultEnum;
use app\common\exception\ZeduException;
use app\common\model\Cars;
use app\common\model\CarsInfo;
use app\common\model\CarsPark;
use app\common\model\Company;
use app\common\model\Personal;
use app\common\model\Terminal;
use app\common\service\CarsService;
use app\common\service\CommonService;
use think\facade\Cache;
use think\facade\Log;


class CarsServiceImpl implements CarsService
{
   
    protected $commonService;
    
    public function __construct(CommonService $commonService)
    {
        $this->commonService = $commonService;
    }
    
    
    public function add(array $data)
    {
        if(!empty($data['carUsage']) && count($data['carUsage'])>1){
            $data['car_usage'] = $data['carUsage'][0];
            $data['relevance'] = $data['carUsage'][1];
        }

        if(!empty($data['holder']) && count($data['holder'])>1){
            $data['holder_type'] = $data['holder'][0];
            $data['holder_id'] = $data['holder'][1];
        }


        $vin = Cars::where(['car_unique_id'=>$data['car_unique_id']])->find();

        $car_sn = Cars::where(['car_sn'=>$data['car_sn']])->find();

        if($vin){
            throw new ZeduException(['code'=>ResultEnum::WRITE_ERROR['code'],'msg'=>'车架号已存在']);
        } 

        if($car_sn){
            throw new ZeduException(['code'=>ResultEnum::WRITE_ERROR['code'],'msg'=>'车牌号已存在']);
        }

        try{
            Cars::create($data,true);
        }catch(\Exception $e){
            Log::record('[ 添加车辆 ]:'.$e->getMessage(),'error');
            return false;
        }
        
        return true;
    }

    public function bandCars($id)
    {
        $cars = Cars::get(['car_id'=>$id]);
        
        if($cars['supplier_no'] == 1376920003){
            
            $obj = new IotCloudClient();
            $res = $obj->band($cars['car_unique_id'],$cars['equipment_id'],$cars['car_sn']);
            
            if($res === false){
                return false;
            }
            
            if($res['result']==0){
                try{
                    $cars->band_status = 1;
                    $cars->save();
                    return true;
                }catch(\Exception $e){
                    Log::record('[ 更新数据库车辆绑定状态 ]:'.$e->getMessage(),'error');
                    return false;
                }
                
            }else{
             
                throw new ZeduException(['code'=>ResultEnum::ERROR['code'],'msg'=>$res['msg']]);
            }
            
        }else{
            throw new ZeduException(['code'=>ResultEnum::PARAM_ERROR['code'],'msg'=>'仅支持S-IOT']);
        }
        
    }
    
  
    public function operate($id,$type)
    {
        $cars = Cars::get(['car_id'=>$id]);
        if ($cars['supplier_no'] == 1376920003) {
            $obj = new IotCloudClient();
            switch ($type) {
                case 1:
                    $res = $obj->operate($cars['car_unique_id'], 'LOCK',1);
                break;
                
                case 2:
                    $res = $obj->operate($cars['car_unique_id'], 'LOCK',0);                
                    break;
                    
                case 3:
                    $res = $obj->operate($cars['car_unique_id'], 'IGNITE',1);                    
                    break;
                    
                case 4:
                    $res = $obj->operate($cars['car_unique_id'], 'IGNITE',0);                   
                    break;
                    
                case 5:
                    $res = $obj->operate($cars['car_unique_id'], 'WHISTLE',1);     
                    break;
                
                default:
                    throw new ZeduException(ResultEnum::PARAM_ERROR);
                break;

            }
            if($res === false){
                return false;
            }
            
            if($res['result'] == 0){
                return true;
            }else{
                throw new ZeduException(['code'=>ResultEnum::ERROR['code'],'msg'=>$res['msg']]);
            } 
 
        }
    }

    public function unBandCars($id)
    {
        $cars = Cars::get(['car_id'=>$id]);

        if($cars['supplier_no'] == 1376920003){
   
            $obj = new IotCloudClient();
            $res = $obj->unBand($cars['car_unique_id']);
            
            if($res === false){
                return false;
            }
            
            if($res['result']==0){
                
                try{
                    $cars->band_status = 0;
                    $cars->save();
                    return true;
                }catch(\Exception $e){
                    Log::record('[ 更新数据库车辆绑定状态 ]:'.$e->getMessage(),'error');
                    return false;
                }
                
            }else{
                throw new ZeduException(['code'=>ResultEnum::ERROR['code'],'msg'=>$res['msg']]);
               
            }
            
        }else{
            throw new ZeduException(['code'=>ResultEnum::PARAM_ERROR['code'],'msg'=>'仅支持S-IOT']);
        }
    }

    public function edit(array $data)
    {
        if(!empty($data['carUsage']) && count($data['carUsage'])>1){
            $data['car_usage'] = $data['carUsage'][0];
            $data['relevance'] = $data['carUsage'][1];
        }
        
        if(!empty($data['holder']) && count($data['holder'])>1){
            $data['holder_type'] = $data['holder'][0];
            $data['holder_id'] = $data['holder'][1];
        }
        
        $cars = new Cars;
        try {
            $cars->allowField(true)->save($data,['car_id'=>$data['car_id']]);
        } catch (\Exception $e) {
            Log::record('[ 更新数据 ]:'.$e->getMessage(),'error');
            return false;
        }
        
        return true;
    }

    public function index($where,$length,$page)
    {
        try {
            $model = Cars::with('brand,agency,carsInfo,carsPark')->withAttr('holderId',function($value,$data){
                if($data['holder_type'] ==0){
                    return Company::where(['id'=>$data['holder_id']])->value('name');
                }else{
                    return Personal::where(['id'=>$data['holder_id']])->value('name');
                }
            })->where($where)->order('car_id', 'desc')
            ->paginate($length,false,[
                'type'     => 'bootstrap',
                'var_page' => 'page',
                'page'=>$page,
            ]); 
            
        } catch (\Exception $e) {
            Log::record('车辆列表:'.$e->getMessage(),'error');
            return false;
        }
        return $model;
    }

    public function details($id)
    {
        $cars = Cars::with('brand,agency')->get(['car_id'=>$id]);
        $carsDetail = [];
        $data = null;
        $address = ['formatted_address'=>null,'street'=>null,'number'=>null];
        if($cars['supplier_no'] == 1376920003){
            $obj = new IotCloudClient();
            $res = $obj->getCarsInfo($cars['car_unique_id']);
            
            if($res === false){
                return false;
            }

            if($res['result'] == 0 && !empty($res['data'])){
                $data = $res['data'][0];
            }
            
        }else if($cars['supplier_no'] == 1376920001){
            $carInfo = CarsInfo::get(['car_unique_id'=>$cars['car_unique_id']]);
            if($carInfo){
                $data = $carInfo;
            }
            
        }

        if($data){
            $result = Gps::geoCode($data['longitude'],$data['latitude']);
            if($result){
                try{
                    
                    $address['formatted_address'] = $result['regeocode']['formatted_address']??'';
                    $address['street'] = $result['regeocode']['addressComponent']['streetNumber']["street"]?$result['regeocode']['addressComponent']['streetNumber']["street"]:'';
                    $address['number'] = $result['regeocode']['addressComponent']['streetNumber']["number"]?$result['regeocode']['addressComponent']['streetNumber']["number"]:'';
                    
                }catch(\Exception $e){
                    Log::record('[ gps取值失败 ]'.$e->getMessage(),'error');
                }  
            }
        }
        
        $carsDetail['cars'] = $cars;
        $carsDetail['info'] = $data;
        $carsDetail['address'] = $address;
        $carsDetail['cars']['holder_name'] = $cars->holder_name??'';
        return $carsDetail; 
    }

    
    public function handleCars($id, $type)
    {
        $cars = Cars::get(['car_id'=>$id]);
        if($cars['supplier_no'] == 1376920003){
            $obj = new IotCloudClient();
            $res = $obj->handleCars($cars['car_unique_id'], $type);
            
            if($res === false){
                return false;
            }
            
            if($res['result'] == 0){
                return true;
            }else{
                throw new ZeduException(['code'=>ResultEnum::ERROR['code'],'msg'=>$res['msg']]);
            } 
        }
    }
    
    public function takePhoto($id)
    {
        $cars = Cars::get(['car_id'=>$id]);
        if($cars['supplier_no'] == 1376920003){
            $obj = new IotCloudClient();
            $res = $obj->photographer($cars['car_unique_id']);
            
            if($res === false){
                return false;
            }
            
            if($res['result'] == 0){
                return true;
            }else{
                throw new ZeduException(['code'=>ResultEnum::ERROR['code'],'msg'=>$res['msg']]);
            } 
        }
    }
    
    public function intercept($id,$type){    
        $cacheData = Cache::get($id);
        
        $status = false;
        switch ($type) {
            case 1:
            case 2:
                $lock = time() - 30;
                if( empty($cacheData['lock']) || $cacheData['lock'] < $lock){
                    $status =true;
                     $cacheData['lock'] =time();
                }
                break;
                
            case 3:
            case 4:
                $lock = time() - 30;
                if(  empty($cacheData['ignite']) || $cacheData['ignite'] < $lock ){
                    $status =true;
                    $cacheData['ignite'] =time();
                }
                break;
                
            case 5:
                $lock = time() - 30;
                if(  empty($cacheData['whiste']) || $cacheData['whiste'] < $lock ){
                    $status =true;
                    $cacheData['whiste'] =time();
                }
                break;
                
            case 6:
                $lock = time() - 30;
                if(  empty($cacheData['cars']) || $cacheData['cars'] < $lock ){
                    $status =true;
                    $cacheData['cars'] =time();
                }
                break;
                
            case 7:
                $lock = time() - 300;
                if(  empty($cacheData['photo']) || $cacheData['photo'] < $lock ){
                    $status =true;
                    $cacheData['photo'] =time();
                }
                break;
                
            default:  
                break;
        }

       Cache::set($id,$cacheData);
       return $status;

    }
    
    public function driver($data){
        if(!empty($data['equipment_id'])){
            $terminal = Terminal::where(['equipment_id'=>$data['equipment_id']])->find();
            if(!$terminal){
                throw new ZeduException(['code'=>ResultEnum::FIND_ERROR['code'],'msg'=>'设备号不存在']);
            }
            $cars = Cars::where(['equipment_id'=>$data['equipment_id']])->find();
            if($cars){
                throw new ZeduException(['code'=>ResultEnum::FIND_ERROR['code'],'msg'=>'设备已绑定']);
            }
        }
        $cardcode = Cars::where(['cardcode'=>$data['cardcode']])->find();
        if($cardcode){
            throw new ZeduException(['code'=>ResultEnum::FIND_ERROR['code'],'msg'=>'卡号已绑定']);
        }

       $carsModel = new Cars;
       $carsData = Cars::get(['car_id'=>$data['car_id']]);
       try {
            $carsModel->startTrans();
            $carsModel->save($data,['car_id' => $data['car_id']]);
            if($carsModel->car_id){
                $info = CarsInfo::where(['car_unique_id'=>$carsData['car_unique_id']])->find();
                $carsInfo = new CarsInfo;
                if($info){
                    $carsInfo->save(['supplier_no'=>$data['supplier_no']],['car_unique_id'=>$carsData['car_unique_id']]);
                    if($carsInfo->supplier_no){
                        $carsModel->commit();
                        return true;
                    }else{
                        $carsModel->rollback();
                        return false;
                    }
                }else{
                    $carsInfo->save(['car_unique_id'=>$carsData['car_unique_id'],'supplier_no'=>$data['supplier_no']]);
                    if($carsInfo->supplier_no){
                        $carsModel->commit();
                        return true;
                    }else{
                        $carsModel->rollback();
                        return false;
                     }
                }
            }else{
                $carsModel->rollback();
                return false;
            }
        } catch (\Exception $e) {
             $carsModel->rollback();
            Log::record('[ 添加设备 ]'.$e->getMessage(),'error');
            return false;
        }

    }

    public function tearDown($id){
        try {
            $int = Cars::where(['car_id'=>$id])->update(['equipment_id'=>'','sim_id'=>'','cardcode'=>'','supplier_no'=>'','sim_card'=>'']);
            
        } catch (\Exception $e) {
            Log::record('[ 拆除设备 ]'.$e->getMessage(),'error');
            return false;
        }
        
        if($int){
            $cars = Cars::get(['car_id'=>$id]);
            try {
                CarsInfo::where(['car_unique_id'=>$cars['car_unique_id']])->delete();
                return true;
            } catch (\Exception $e) {
                Log::record('[ carsInfo表删除数据 ]'.$e->getMessage(),'error');
                return false;
            }
        }
    }
    public function del(int $id)
    {
        $cars = Cars::get(['car_id'=>$id]);
        if($cars['band_status'] == 1){
            throw new ZeduException(['code'=>ResultEnum::OPERATE_ERROR['code'],'msg'=>'删除失败,请解除绑定']);
        }
        $res  = Cars::where(['car_id'=>$id])->delete();
        if(!$res){
            return fasle;
        }
        return true;
    }
    
    public function uploadFile(array $data)
    {
        $uploadData = [];
        $number = ['updateNum'=>0,'insertNum'=>0];
        $model = new Cars;
        if(!empty($data)){
            foreach ($data as $value) {    
                $uploadData['car_sn'] = trim($value[0]??'');
                $uploadData['motor_id'] = $value[2]??'';
                $uploadData['car_name'] = $value[3]??'';
                $brand = [];
                $brand['name'] = $value[4]??'';
                $uploadData['brand_id'] = $this->commonService->findBrand($brand);
                $carBreed = $value[5]??'';
                switch ($carBreed) {
                    case '小轿车':
                    $uploadData['car_breed'] = 0;
                    break;
                    case 'SUV':
                        $uploadData['car_breed'] = 1;
                        break;
                    case '中巴':
                        $uploadData['car_breed'] = 2;
                        break;
                    default:
                        $uploadData['car_breed'] = null;
                    break;
                }
                $carUsage = $value[6]??'';
                $uploadData['car_usage'] = $this->carUsage($carUsage);
                $relevance = $value[7]??'';
                $uploadData['relevance'] = $this->relevance($relevance);
                $company = [];
                $company['name'] = $value[8]??'';
                $uploadData['holder_id'] = $this->findCompany($company);
                if($uploadData['holder_id']){
                    $uploadData['holder_typer'] = 0;
                }
                $agency = [];
                $agency['name'] = $value[9]??'';
                $uploadData['agency_id'] = $this->commonService->findAgency($agency);
                $carPark = [];
                $carPark['name'] = $value[10]??'';
                $uploadData['car_park'] = $this->findPark($carPark);
                
                $cars = Cars::where(['car_unique_id'=>trim($value[1])])->find();
                 if($cars){
                   try {
                        $model->update($uploadData,['car_id'=>$cars['car_id']]);
                        $number['updateNum']++;
                    } catch (\Exception $e) {
                        Log::record('[ 车辆列表更新数据 ]:'.$e->getMessage(),'error');
                        return false;
                    }
                    
                }else{
                    $uploadData['car_unique_id'] = trim($value[1]??'');
                    try {
                        $model->create($uploadData);
                        $number['insertNum']++; 
                    } catch (\Exception $e) {
                        Log::record('[ 车辆列表新增数据 ]:'.$e->getMessage(),'error');
                        return false;
                    }
                }  
                
            }
            return $number;
        }
    }
    

    public function carUsage($param){
        $data = 0;
        switch ($param) {
            case '库存':          
                $data = 1;
                break;
            case '分时租赁':       
                $data = 2;
                break;
            case '长租':    
                $data = 3;
                break;
            case '以租代购': 
                $data = 4;
                break;
            case '企业用车':
                $data = 5;
                break;
            case '共享用车':  
                $data = 6;
                break;
            case '公务用车':    
                $data = 7;
                break;
            case '自测用车':    
                $data = 8;
                break;
            case '销售':      
                $data = 9;
                break;   
            default:
                $data = null;
                break;
        }
        return $data;
    }
    
    public function relevance($param){
       $data = 0;
        switch ($param) {
            case '待整备':
                $data = 1;
                break;
            case '整备完成': 
                $data = 2;
                break;
            case '分时租赁':
                $data = 3;
                break;
            case '企业用车': 
                $data = 4;
                break;
            case '共享用车':   
                $data = 5;
                break;
            case '长租':     
                $data = 6;
                break;
            case '自测用车':       
                $data = 7;
                break;
            case '以租代购':       
                $data = 8;
                break;
            case '在修待修':         
                $data = 9;
                break;
            case '体验用车':        
                $data = 10;
                break;
            case '公务用车':         
                $data = 11;
                break;
            case '销售售出':    
                $data = 12;
                break;
            case '展示用车':         
                $data = 13;
                break;
            case '待售出':   
                $data = 14;
                break;
            case '办理违章':
                $data = 15;
                break;
            case '出险':
                $data = 16;
                break;
            case '紧急调用':
                $data = 17;
                break;
            case '设备故障':
                $data = 18;
                break;
            case '报废':
                $data = 19;
                break;
            default:
                $data = null;
                break;
        }
        return $data;
    }

    public function findCompany($param){
        if(!empty($param['name'])){
            $data = Company::where($param)->value('id');
            if($data){
                return $data;
            }else{
                throw new ZeduException(['code'=>ResultEnum::FIND_ERROR['code'],'msg'=>$param['name'].'不存在']);
            }
        }else{
            throw new ZeduException(['code'=>ResultEnum::FIND_ERROR['code'],'msg'=>'机动车所属权不能为空']);
        }
    }
    
    public function findPark($param){
        if(!empty($param['name'])){
            $data = CarsPark::where($param)->value('id');
            if($data){
                return $data;
            }else{
                throw new ZeduException(['code'=>ResultEnum::FIND_ERROR['code'],'msg'=>$param['name'].'不存在']);
            }
        }else{
            return '';
        }
    }
    public function history(String $vin, int $timeStart, int $timeEnd)
    {
        $obj = new IotCloudClient();
        $res = $obj->previous($vin, $timeStart, $timeEnd);
        
        if($res === false){
            return false;
        }
        $data = [];
        if($res['result'] == 0 && !empty($res['data'])){
            $data = $res['data'];
        }else{
            throw new ZeduException(['code'=>ResultEnum::FIND_ERROR['code'],'msg'=>'暂无数据']);
        }
        return $data;
    }

    
    
}

